#include "ODBCWrapper.h"

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <iostream>

using namespace std;

/*static*/ DynLib *ODBCWrapper::odbcLib = NULL;

/*static*/ _fn_SQLAllocConnectType* ODBCWrapper::_fn_SQLAllocConnect = NULL;
/*static*/ _fn_SQLAllocEnvType* ODBCWrapper::_fn_SQLAllocEnv = NULL;
/*static*/ _fn_SQLAllocStmtType* ODBCWrapper::_fn_SQLAllocStmt = NULL;
/*static*/ _fn_SQLAllocHandleType* ODBCWrapper::_fn_SQLAllocHandle = NULL;
/*static*/ _fn_SQLBindColType* ODBCWrapper::_fn_SQLBindCol = NULL;
/*static*/ _fn_SQLBindParamType* ODBCWrapper::_fn_SQLBindParam = NULL;
/*static*/ _fn_SQLCancelType* ODBCWrapper::_fn_SQLCancel = NULL;
/*static*/ _fn_SQLCloseCursorType* ODBCWrapper::_fn_SQLCloseCursor = NULL;
/*static*/ _fn_SQLColAttributeType* ODBCWrapper::_fn_SQLColAttribute = NULL;
/*static*/ _fn_SQLColumnsType* ODBCWrapper::_fn_SQLColumns = NULL;
/*static*/ _fn_SQLConnectType* ODBCWrapper::_fn_SQLConnect = NULL;
/*static*/ _fn_SQLDriverConnectType* ODBCWrapper::_fn_SQLDriverConnect = NULL;
/*static*/ _fn_SQLCopyDescType* ODBCWrapper::_fn_SQLCopyDesc = NULL;
/*static*/ _fn_SQLDataSourcesType* ODBCWrapper::_fn_SQLDataSources = NULL;
/*static*/ _fn_SQLDescribeColType* ODBCWrapper::_fn_SQLDescribeCol = NULL;
/*static*/ _fn_SQLDisconnectType* ODBCWrapper::_fn_SQLDisconnect = NULL;
/*static*/ _fn_SQLEndTranType* ODBCWrapper::_fn_SQLEndTran = NULL;
/*static*/ _fn_SQLErrorType* ODBCWrapper::_fn_SQLError = NULL;
/*static*/ _fn_SQLExecDirectType* ODBCWrapper::_fn_SQLExecDirect = NULL;
/*static*/ _fn_SQLExecuteType* ODBCWrapper::_fn_SQLExecute = NULL;
/*static*/ _fn_SQLFetchType* ODBCWrapper::_fn_SQLFetch = NULL;
/*static*/ _fn_SQLFetchScrollType* ODBCWrapper::_fn_SQLFetchScroll = NULL;
/*static*/ _fn_SQLFreeConnectType* ODBCWrapper::_fn_SQLFreeConnect = NULL;
/*static*/ _fn_SQLFreeEnvType* ODBCWrapper::_fn_SQLFreeEnv = NULL;
/*static*/ _fn_SQLFreeStmtType* ODBCWrapper::_fn_SQLFreeStmt = NULL;
/*static*/ _fn_SQLFreeHandleType* ODBCWrapper::_fn_SQLFreeHandle = NULL;
/*static*/ _fn_SQLGetConnectAttrType* ODBCWrapper::_fn_SQLGetConnectAttr = NULL;
/*static*/ _fn_SQLGetConnectOptionType* ODBCWrapper::_fn_SQLGetConnectOption = NULL;
/*static*/ _fn_SQLGetCursorNameType* ODBCWrapper::_fn_SQLGetCursorName = NULL;
/*static*/ _fn_SQLGetDataType* ODBCWrapper::_fn_SQLGetData = NULL;
/*static*/ _fn_SQLGetDescFieldType* ODBCWrapper::_fn_SQLGetDescField = NULL;
/*static*/ _fn_SQLGetDescRecType* ODBCWrapper::_fn_SQLGetDescRec = NULL;
/*static*/ _fn_SQLGetDiagFieldType* ODBCWrapper::_fn_SQLGetDiagField = NULL;
/*static*/ _fn_SQLGetDiagRecType* ODBCWrapper::_fn_SQLGetDiagRec = NULL;
/*static*/ _fn_SQLGetEnvAttrType* ODBCWrapper::_fn_SQLGetEnvAttr = NULL;
/*static*/ _fn_SQLGetInfoType* ODBCWrapper::_fn_SQLGetInfo = NULL;
/*static*/ _fn_SQLGetStmtAttrType* ODBCWrapper::_fn_SQLGetStmtAttr = NULL;
/*static*/ _fn_SQLGetStmtOptionType* ODBCWrapper::_fn_SQLGetStmtOption = NULL;
/*static*/ _fn_SQLGetTypeInfoType* ODBCWrapper::_fn_SQLGetTypeInfo = NULL;
/*static*/ _fn_SQLNumResultColsType* ODBCWrapper::_fn_SQLNumResultCols = NULL;
/*static*/ _fn_SQLParamDataType* ODBCWrapper::_fn_SQLParamData = NULL;
/*static*/ _fn_SQLPrepareType* ODBCWrapper::_fn_SQLPrepare = NULL;
/*static*/ _fn_SQLPutDataType* ODBCWrapper::_fn_SQLPutData = NULL;
/*static*/ _fn_SQLRowCountType* ODBCWrapper::_fn_SQLRowCount = NULL;
/*static*/ _fn_SQLSetConnectAttrType* ODBCWrapper::_fn_SQLSetConnectAttr = NULL;
/*static*/ _fn_SQLSetConnectOptionType* ODBCWrapper::_fn_SQLSetConnectOption = NULL;
/*static*/ _fn_SQLSetCursorNameType* ODBCWrapper::_fn_SQLSetCursorName = NULL;
/*static*/ _fn_SQLSetDescFieldType* ODBCWrapper::_fn_SQLSetDescField = NULL;
/*static*/ _fn_SQLSetDescRecType* ODBCWrapper::_fn_SQLSetDescRec = NULL;
/*static*/ _fn_SQLSetEnvAttrType* ODBCWrapper::_fn_SQLSetEnvAttr = NULL;
/*static*/ _fn_SQLSetStmtAttrType* ODBCWrapper::_fn_SQLSetStmtAttr = NULL;
/*static*/ _fn_SQLSetStmtOptionType* ODBCWrapper::_fn_SQLSetStmtOption = NULL;
/*static*/ _fn_SQLSpecialColumnsType* ODBCWrapper::_fn_SQLSpecialColumns = NULL;
/*static*/ _fn_SQLStatisticsType* ODBCWrapper::_fn_SQLStatistics = NULL;
/*static*/ _fn_SQLTablesType* ODBCWrapper::_fn_SQLTables = NULL;
/*static*/ _fn_SQLTransactType* ODBCWrapper::_fn_SQLTransact = NULL;
/*static*/ _fn_SQLSetParamType* ODBCWrapper::_fn_SQLSetParam = NULL;

ODBCWrapper::ODBCWrapper(const char *_libraryPath) {
    initDone = false;
    libraryPath = _libraryPath;
}

ODBCWrapper::~ODBCWrapper() {
}

bool ODBCWrapper::init() {

    //TODO: add mutex

    if (initDone) {
        return true;
    }

	odbcLib = new DynLib(libraryPath);

	// get function pointers
	_fn_SQLAllocConnect = (_fn_SQLAllocConnectType*) resolve("SQLAllocConnect");
	if (_fn_SQLAllocConnect == NULL) {
		//return false;
	}
	_fn_SQLAllocEnv = (_fn_SQLAllocEnvType*) resolve("SQLAllocEnv");
	if (_fn_SQLAllocEnv == NULL) {
		//return false;
	}
	_fn_SQLAllocStmt = (_fn_SQLAllocStmtType*) resolve("SQLAllocStmt");
	if (_fn_SQLAllocStmt == NULL) {
		//return false;
	}
	_fn_SQLAllocHandle = (_fn_SQLAllocHandleType*) resolve("SQLAllocHandle");
	if (_fn_SQLAllocHandle == NULL) {
		//return false;
	}
	_fn_SQLBindCol = (_fn_SQLBindColType*) resolve("SQLBindCol");
	if (_fn_SQLBindCol == NULL) {
		//return false;
	}
	_fn_SQLBindParam = (_fn_SQLBindParamType*) resolve("SQLBindParam");
	if (_fn_SQLBindParam == NULL) {
//		//return false;
	}
	_fn_SQLCancel = (_fn_SQLCancelType*) resolve("SQLCancel");
	if (_fn_SQLCancel == NULL) {
		//return false;
	}
	_fn_SQLCloseCursor = (_fn_SQLCloseCursorType*) resolve("SQLCloseCursor");
	if (_fn_SQLCloseCursor == NULL) {
		//return false;
	}
	_fn_SQLColAttribute = (_fn_SQLColAttributeType*) resolve("SQLColAttribute");
	if (_fn_SQLColAttribute == NULL) {
		//return false;
	}
	_fn_SQLColumns = (_fn_SQLColumnsType*) resolve("SQLColumns");
	if (_fn_SQLColumns == NULL) {
		//return false;
	}
	_fn_SQLConnect = (_fn_SQLConnectType*) resolve("SQLConnect");
	if (_fn_SQLConnect == NULL) {
		//return false;
	}
	_fn_SQLDriverConnect = (_fn_SQLDriverConnectType*) resolve("SQLDriverConnect");
	if (_fn_SQLDriverConnect == NULL) {
		//return false;
	}
	_fn_SQLCopyDesc = (_fn_SQLCopyDescType*) resolve("SQLCopyDesc");
	if (_fn_SQLCopyDesc == NULL) {
		//return false;
	}
	_fn_SQLDataSources = (_fn_SQLDataSourcesType*) resolve("SQLDataSources");
	if (_fn_SQLDataSources == NULL) {
		//return false;
	}
	_fn_SQLDescribeCol = (_fn_SQLDescribeColType*) resolve("SQLDescribeCol");
	if (_fn_SQLDescribeCol == NULL) {
		//return false;
	}
	_fn_SQLDisconnect = (_fn_SQLDisconnectType*) resolve("SQLDisconnect");
	if (_fn_SQLDisconnect == NULL) {
		//return false;
	}
	_fn_SQLEndTran = (_fn_SQLEndTranType*) resolve("SQLEndTran");
	if (_fn_SQLEndTran == NULL) {
		//return false;
	}
	_fn_SQLError = (_fn_SQLErrorType*) resolve("SQLError");
	if (_fn_SQLError == NULL) {
		//return false;
	}
	_fn_SQLExecDirect = (_fn_SQLExecDirectType*) resolve("SQLExecDirect");
	if (_fn_SQLExecDirect == NULL) {
		//return false;
	}
	_fn_SQLExecute = (_fn_SQLExecuteType*) resolve("SQLExecute");
	if (_fn_SQLExecute == NULL) {
		//return false;
	}
	_fn_SQLFetch = (_fn_SQLFetchType*) resolve("SQLFetch");
	if (_fn_SQLFetch == NULL) {
		//return false;
	}
	_fn_SQLFetchScroll = (_fn_SQLFetchScrollType*) resolve("SQLFetchScroll");
	if (_fn_SQLFetchScroll == NULL) {
		//return false;
	}
	_fn_SQLFreeConnect = (_fn_SQLFreeConnectType*) resolve("SQLFreeConnect");
	if (_fn_SQLFreeConnect == NULL) {
		//return false;
	}
	_fn_SQLFreeEnv = (_fn_SQLFreeEnvType*) resolve("SQLFreeEnv");
	if (_fn_SQLFreeEnv == NULL) {
		//return false;
	}
	_fn_SQLFreeStmt = (_fn_SQLFreeStmtType*) resolve("SQLFreeStmt");
	if (_fn_SQLFreeStmt == NULL) {
		//return false;
	}
	_fn_SQLFreeHandle = (_fn_SQLFreeHandleType*) resolve("SQLFreeHandle");
	if (_fn_SQLFreeHandle == NULL) {
		//return false;
	}
	_fn_SQLGetConnectAttr = (_fn_SQLGetConnectAttrType*) resolve("SQLGetConnectAttr");
	if (_fn_SQLGetConnectAttr == NULL) {
		//return false;
	}
	_fn_SQLGetConnectOption = (_fn_SQLGetConnectOptionType*) resolve("SQLGetConnectOption");
	if (_fn_SQLGetConnectOption == NULL) {
		//return false;
	}
	_fn_SQLGetCursorName = (_fn_SQLGetCursorNameType*) resolve("SQLGetCursorName");
	if (_fn_SQLGetCursorName == NULL) {
		//return false;
	}
	_fn_SQLGetData = (_fn_SQLGetDataType*) resolve("SQLGetData");
	if (_fn_SQLGetData == NULL) {
		//return false;
	}
	_fn_SQLGetDescField = (_fn_SQLGetDescFieldType*) resolve("SQLGetDescField");
	if (_fn_SQLGetDescField == NULL) {
		//return false;
	}
	_fn_SQLGetDescRec = (_fn_SQLGetDescRecType*) resolve("SQLGetDescRec");
	if (_fn_SQLGetDescRec == NULL) {
		//return false;
	}
	_fn_SQLGetDiagField = (_fn_SQLGetDiagFieldType*) resolve("SQLGetDiagField");
	if (_fn_SQLGetDiagField == NULL) {
		//return false;
	}
	_fn_SQLGetDiagRec = (_fn_SQLGetDiagRecType*) resolve("SQLGetDiagRec");
	if (_fn_SQLGetDiagRec == NULL) {
		//return false;
	}
	_fn_SQLGetEnvAttr = (_fn_SQLGetEnvAttrType*) resolve("SQLGetEnvAttr");
	if (_fn_SQLGetEnvAttr == NULL) {
		//return false;
	}
	_fn_SQLGetInfo = (_fn_SQLGetInfoType*) resolve("SQLGetInfo");
	if (_fn_SQLGetInfo == NULL) {
		//return false;
	}
	_fn_SQLGetStmtAttr = (_fn_SQLGetStmtAttrType*) resolve("SQLGetStmtAttr");
	if (_fn_SQLGetStmtAttr == NULL) {
		//return false;
	}
	_fn_SQLGetStmtOption = (_fn_SQLGetStmtOptionType*) resolve("SQLGetStmtOption");
	if (_fn_SQLGetStmtOption == NULL) {
		//return false;
	}
	_fn_SQLGetTypeInfo = (_fn_SQLGetTypeInfoType*) resolve("SQLGetTypeInfo");
	if (_fn_SQLGetTypeInfo == NULL) {
		//return false;
	}
	_fn_SQLNumResultCols = (_fn_SQLNumResultColsType*) resolve("SQLNumResultCols");
	if (_fn_SQLNumResultCols == NULL) {
		//return false;
	}
	_fn_SQLParamData = (_fn_SQLParamDataType*) resolve("SQLParamData");
	if (_fn_SQLParamData == NULL) {
		//return false;
	}
	_fn_SQLPrepare = (_fn_SQLPrepareType*) resolve("SQLPrepare");
	if (_fn_SQLPrepare == NULL) {
		//return false;
	}
	_fn_SQLPutData = (_fn_SQLPutDataType*) resolve("SQLPutData");
	if (_fn_SQLPutData == NULL) {
		//return false;
	}
	_fn_SQLRowCount = (_fn_SQLRowCountType*) resolve("SQLRowCount");
	if (_fn_SQLRowCount == NULL) {
		//return false;
	}
	_fn_SQLSetConnectAttr = (_fn_SQLSetConnectAttrType*) resolve("SQLSetConnectAttr");
	if (_fn_SQLSetConnectAttr == NULL) {
		//return false;
	}
	_fn_SQLSetConnectOption = (_fn_SQLSetConnectOptionType*) resolve("SQLSetConnectOption");
	if (_fn_SQLSetConnectOption == NULL) {
		//return false;
	}
	_fn_SQLSetCursorName = (_fn_SQLSetCursorNameType*) resolve("SQLSetCursorName");
	if (_fn_SQLSetCursorName == NULL) {
		//return false;
	}
	_fn_SQLSetDescField = (_fn_SQLSetDescFieldType*) resolve("SQLSetDescField");
	if (_fn_SQLSetDescField == NULL) {
		//return false;
	}
	_fn_SQLSetDescRec = (_fn_SQLSetDescRecType*) resolve("SQLSetDescRec");
	if (_fn_SQLSetDescRec == NULL) {
		//return false;
	}
	_fn_SQLSetEnvAttr = (_fn_SQLSetEnvAttrType*) resolve("SQLSetEnvAttr");
	if (_fn_SQLSetEnvAttr == NULL) {
		//return false;
	}
	_fn_SQLSetStmtAttr = (_fn_SQLSetStmtAttrType*) resolve("SQLSetStmtAttr");
	if (_fn_SQLSetStmtAttr == NULL) {
		//return false;
	}
	_fn_SQLSetStmtOption = (_fn_SQLSetStmtOptionType*) resolve("SQLSetStmtOption");
	if (_fn_SQLSetStmtOption == NULL) {
		//return false;
	}
	_fn_SQLSpecialColumns = (_fn_SQLSpecialColumnsType*) resolve("SQLSpecialColumns");
	if (_fn_SQLSpecialColumns == NULL) {
		//return false;
	}
	_fn_SQLStatistics = (_fn_SQLStatisticsType*) resolve("SQLStatistics");
	if (_fn_SQLStatistics == NULL) {
		//return false;
	}
	_fn_SQLTables = (_fn_SQLTablesType*) resolve("SQLTables");
	if (_fn_SQLTables == NULL) {
		//return false;
	}
	_fn_SQLTransact = (_fn_SQLTransactType*) resolve("SQLTransact");
	if (_fn_SQLTransact == NULL) {
		//return false;
	}
	_fn_SQLSetParam = (_fn_SQLSetParamType*) resolve("SQLSetParam");
	if (_fn_SQLSetParam == NULL) {
		//return false;
	}

    initDone = true;

    return true;
}

void *ODBCWrapper::resolve(const char *functionName) {
	void * ret = odbcLib->get_function(functionName);
	if (ret==NULL) {
		cerr << "Failed to resolve function " << functionName << endl;
	}
	return ret;
}

//// ODBC FUNCTIONS /////


SQLRETURN SQL_API ODBCWrapper::SQLAllocConnect(SQLHENV EnvironmentHandle, SQLHDBC * ConnectionHandle)  {
	if (_fn_SQLAllocConnect==NULL) {
		cerr << "NULL function pointer for SQLAllocConnect" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLAllocConnect(EnvironmentHandle, ConnectionHandle);
}


SQLRETURN SQL_API ODBCWrapper::SQLAllocEnv(SQLHENV * EnvironmentHandle)  {
	if (_fn_SQLAllocEnv==NULL) {
		cerr << "NULL function pointer for SQLAllocEnv" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLAllocEnv(EnvironmentHandle);
}


SQLRETURN SQL_API ODBCWrapper::SQLAllocStmt(SQLHDBC ConnectionHandle, SQLHSTMT * StatementHandle)  {
	if (_fn_SQLAllocStmt==NULL) {
		cerr << "NULL function pointer for SQLAllocStmt" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLAllocStmt(ConnectionHandle, StatementHandle);
}


SQLRETURN SQL_API ODBCWrapper::SQLAllocHandle(SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE * OutputHandle)  {
	if (_fn_SQLAllocHandle==NULL) {
		cerr << "NULL function pointer for SQLAllocHandle" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLAllocHandle(HandleType, InputHandle, OutputHandle);
}


SQLRETURN SQL_API ODBCWrapper::SQLBindCol(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, SQLPOINTER TargetValue, SQLLEN BufferLength, SQLLEN * StrLen_or_Ind)  {
	if (_fn_SQLBindCol==NULL) {
		cerr << "NULL function pointer for SQLBindCol" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLBindCol(StatementHandle, ColumnNumber, TargetType, TargetValue, BufferLength, StrLen_or_Ind);
}


SQLRETURN SQL_API ODBCWrapper::SQLBindParam(SQLHSTMT StatementHandle, SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType, SQLSMALLINT ParameterType, SQLULEN LengthPrecision, SQLSMALLINT ParameterScale, SQLPOINTER ParameterValue, SQLLEN * StrLen_or_Ind)  {
	if (_fn_SQLBindParam==NULL) {
		cerr << "NULL function pointer for SQLBindParam" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLBindParam(StatementHandle, ParameterNumber, ValueType, ParameterType, LengthPrecision, ParameterScale, ParameterValue, StrLen_or_Ind);
}


SQLRETURN SQL_API ODBCWrapper::SQLCancel(SQLHSTMT StatementHandle)  {
	if (_fn_SQLCancel==NULL) {
		cerr << "NULL function pointer for SQLCancel" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLCancel(StatementHandle);
}


SQLRETURN SQL_API ODBCWrapper::SQLCloseCursor(SQLHSTMT StatementHandle)  {
	if (_fn_SQLCloseCursor==NULL) {
		cerr << "NULL function pointer for SQLCloseCursor" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLCloseCursor(StatementHandle);
}


SQLRETURN SQL_API ODBCWrapper::SQLColAttribute(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLUSMALLINT FieldIdentifier, SQLPOINTER CharacterAttribute, SQLSMALLINT BufferLength, SQLSMALLINT * StringLength, SQLLEN * NumericAttribute)  {
	if (_fn_SQLColAttribute==NULL) {
		cerr << "NULL function pointer for SQLColAttribute" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLColAttribute(StatementHandle, ColumnNumber, FieldIdentifier, CharacterAttribute, BufferLength, StringLength, NumericAttribute);
}


SQLRETURN SQL_API ODBCWrapper::SQLColumns(SQLHSTMT StatementHandle, SQLCHAR * CatalogName, SQLSMALLINT NameLength1, SQLCHAR * SchemaName, SQLSMALLINT NameLength2, SQLCHAR * TableName, SQLSMALLINT NameLength3, SQLCHAR * ColumnName, SQLSMALLINT NameLength4)  {
	if (_fn_SQLColumns==NULL) {
		cerr << "NULL function pointer for SQLColumns" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLColumns(StatementHandle, CatalogName, NameLength1, SchemaName, NameLength2, TableName, NameLength3, ColumnName, NameLength4);
}


SQLRETURN SQL_API ODBCWrapper::SQLConnect(SQLHDBC ConnectionHandle, SQLCHAR * ServerName, SQLSMALLINT NameLength1, SQLCHAR * UserName, SQLSMALLINT NameLength2, SQLCHAR * Authentication, SQLSMALLINT NameLength3)  {
	if (_fn_SQLConnect==NULL) {
		cerr << "NULL function pointer for SQLConnect" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLConnect(ConnectionHandle, ServerName, NameLength1, UserName, NameLength2, Authentication, NameLength3);
}


SQLRETURN SQL_API ODBCWrapper::SQLDriverConnect( SQLHDBC            hdbc, SQLHWND            hwnd, SQLCHAR               *szConnStrIn, SQLSMALLINT        cbConnStrIn, SQLCHAR           *szConnStrOut, SQLSMALLINT        cbConnStrOutMax, SQLSMALLINT           *pcbConnStrOut, SQLUSMALLINT       fDriverCompletion)  {
	if (_fn_SQLDriverConnect==NULL) {
		cerr << "NULL function pointer for SQLDriverConnect" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLDriverConnect(hdbc, hwnd, szConnStrIn, cbConnStrIn, szConnStrOut, cbConnStrOutMax, pcbConnStrOut, fDriverCompletion);
}


SQLRETURN SQL_API ODBCWrapper::SQLCopyDesc(SQLHDESC SourceDescHandle, SQLHDESC TargetDescHandle)  {
	if (_fn_SQLCopyDesc==NULL) {
		cerr << "NULL function pointer for SQLCopyDesc" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLCopyDesc(SourceDescHandle, TargetDescHandle);
}


SQLRETURN SQL_API ODBCWrapper::SQLDataSources(SQLHENV EnvironmentHandle, SQLUSMALLINT Direction, SQLCHAR * ServerName, SQLSMALLINT BufferLength1, SQLSMALLINT * NameLength1, SQLCHAR * Description, SQLSMALLINT BufferLength2, SQLSMALLINT * NameLength2)  {
	if (_fn_SQLDataSources==NULL) {
		cerr << "NULL function pointer for SQLDataSources" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLDataSources(EnvironmentHandle, Direction, ServerName, BufferLength1, NameLength1, Description, BufferLength2, NameLength2);
}


SQLRETURN SQL_API ODBCWrapper::SQLDescribeCol(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLCHAR * ColumnName, SQLSMALLINT BufferLength, SQLSMALLINT * NameLength, SQLSMALLINT * DataType, SQLULEN * ColumnSize, SQLSMALLINT * DecimalDigits, SQLSMALLINT * Nullable)  {
	if (_fn_SQLDescribeCol==NULL) {
		cerr << "NULL function pointer for SQLDescribeCol" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLDescribeCol(StatementHandle, ColumnNumber, ColumnName, BufferLength, NameLength, DataType, ColumnSize, DecimalDigits, Nullable);
}


SQLRETURN SQL_API ODBCWrapper::SQLDisconnect(SQLHDBC ConnectionHandle)  {
	if (_fn_SQLDisconnect==NULL) {
		cerr << "NULL function pointer for SQLDisconnect" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLDisconnect(ConnectionHandle);
}


SQLRETURN SQL_API ODBCWrapper::SQLEndTran(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT CompletionType)  {
	if (_fn_SQLEndTran==NULL) {
		cerr << "NULL function pointer for SQLEndTran" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLEndTran(HandleType, Handle, CompletionType);
}


SQLRETURN SQL_API ODBCWrapper::SQLError(SQLHENV EnvironmentHandle, SQLHDBC ConnectionHandle, SQLHSTMT StatementHandle, SQLCHAR * Sqlstate, SQLINTEGER * NativeError, SQLCHAR * MessageText, SQLSMALLINT BufferLength, SQLSMALLINT * TextLength)  {
	if (_fn_SQLError==NULL) {
		cerr << "NULL function pointer for SQLError" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLError(EnvironmentHandle, ConnectionHandle, StatementHandle, Sqlstate, NativeError, MessageText, BufferLength, TextLength);
}


SQLRETURN SQL_API ODBCWrapper::SQLExecDirect(SQLHSTMT StatementHandle, SQLCHAR * StatementText, SQLINTEGER TextLength)  {
	if (_fn_SQLExecDirect==NULL) {
		cerr << "NULL function pointer for SQLExecDirect" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLExecDirect(StatementHandle, StatementText, TextLength);
}


SQLRETURN SQL_API ODBCWrapper::SQLExecute(SQLHSTMT StatementHandle)  {
	if (_fn_SQLExecute==NULL) {
		cerr << "NULL function pointer for SQLExecute" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLExecute(StatementHandle);
}


SQLRETURN SQL_API ODBCWrapper::SQLFetch(SQLHSTMT StatementHandle)  {
	if (_fn_SQLFetch==NULL) {
		cerr << "NULL function pointer for SQLFetch" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLFetch(StatementHandle);
}


SQLRETURN SQL_API ODBCWrapper::SQLFetchScroll(SQLHSTMT StatementHandle, SQLSMALLINT FetchOrientation, SQLLEN FetchOffset)  {
	if (_fn_SQLFetchScroll==NULL) {
		cerr << "NULL function pointer for SQLFetchScroll" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLFetchScroll(StatementHandle, FetchOrientation, FetchOffset);
}


SQLRETURN SQL_API ODBCWrapper::SQLFreeConnect(SQLHDBC ConnectionHandle)  {
	if (_fn_SQLFreeConnect==NULL) {
		cerr << "NULL function pointer for SQLFreeConnect" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLFreeConnect(ConnectionHandle);
}


SQLRETURN SQL_API ODBCWrapper::SQLFreeEnv(SQLHENV EnvironmentHandle)  {
	if (_fn_SQLFreeEnv==NULL) {
		cerr << "NULL function pointer for SQLFreeEnv" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLFreeEnv(EnvironmentHandle);
}


SQLRETURN SQL_API ODBCWrapper::SQLFreeStmt(SQLHSTMT StatementHandle, SQLUSMALLINT Option)  {
	if (_fn_SQLFreeStmt==NULL) {
		cerr << "NULL function pointer for SQLFreeStmt" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLFreeStmt(StatementHandle, Option);
}


SQLRETURN SQL_API ODBCWrapper::SQLFreeHandle(SQLSMALLINT HandleType, SQLHANDLE Handle)  {
	if (_fn_SQLFreeHandle==NULL) {
		cerr << "NULL function pointer for SQLFreeHandle" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLFreeHandle(HandleType, Handle);
}


SQLRETURN SQL_API ODBCWrapper::SQLGetConnectAttr(SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER * StringLength)  {
	if (_fn_SQLGetConnectAttr==NULL) {
		cerr << "NULL function pointer for SQLGetConnectAttr" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLGetConnectAttr(ConnectionHandle, Attribute, Value, BufferLength, StringLength);
}


SQLRETURN SQL_API ODBCWrapper::SQLGetConnectOption(SQLHDBC ConnectionHandle, SQLUSMALLINT Option, SQLPOINTER Value)  {
	if (_fn_SQLGetConnectOption==NULL) {
		cerr << "NULL function pointer for SQLGetConnectOption" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLGetConnectOption(ConnectionHandle, Option, Value);
}


SQLRETURN SQL_API ODBCWrapper::SQLGetCursorName(SQLHSTMT StatementHandle, SQLCHAR * CursorName, SQLSMALLINT BufferLength, SQLSMALLINT * NameLength)  {
	if (_fn_SQLGetCursorName==NULL) {
		cerr << "NULL function pointer for SQLGetCursorName" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLGetCursorName(StatementHandle, CursorName, BufferLength, NameLength);
}


SQLRETURN SQL_API ODBCWrapper::SQLGetData(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, SQLPOINTER TargetValue, SQLLEN BufferLength, SQLLEN * StrLen_or_Ind)  {
	if (_fn_SQLGetData==NULL) {
		cerr << "NULL function pointer for SQLGetData" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLGetData(StatementHandle, ColumnNumber, TargetType, TargetValue, BufferLength, StrLen_or_Ind);
}


SQLRETURN SQL_API ODBCWrapper::SQLGetDescField(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER * StringLength)  {
	if (_fn_SQLGetDescField==NULL) {
		cerr << "NULL function pointer for SQLGetDescField" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLGetDescField(DescriptorHandle, RecNumber, FieldIdentifier, Value, BufferLength, StringLength);
}


SQLRETURN SQL_API ODBCWrapper::SQLGetDescRec(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, SQLCHAR * Name, SQLSMALLINT BufferLength, SQLSMALLINT * StringLength, SQLSMALLINT * Type, SQLSMALLINT * SubType, SQLLEN * Length, SQLSMALLINT * Precision, SQLSMALLINT * Scale, SQLSMALLINT * Nullable)  {
	if (_fn_SQLGetDescRec==NULL) {
		cerr << "NULL function pointer for SQLGetDescRec" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLGetDescRec(DescriptorHandle, RecNumber, Name, BufferLength, StringLength, Type, SubType, Length, Precision, Scale, Nullable);
}


SQLRETURN SQL_API ODBCWrapper::SQLGetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier, SQLPOINTER DiagInfo, SQLSMALLINT BufferLength, SQLSMALLINT * StringLength)  {
	if (_fn_SQLGetDiagField==NULL) {
		cerr << "NULL function pointer for SQLGetDiagField" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLGetDiagField(HandleType, Handle, RecNumber, DiagIdentifier, DiagInfo, BufferLength, StringLength);
}


SQLRETURN SQL_API ODBCWrapper::SQLGetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecNumber, SQLCHAR * Sqlstate, SQLINTEGER * NativeError, SQLCHAR * MessageText, SQLSMALLINT BufferLength, SQLSMALLINT * TextLength)  {
	if (_fn_SQLGetDiagRec==NULL) {
		cerr << "NULL function pointer for SQLGetDiagRec" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLGetDiagRec(HandleType, Handle, RecNumber, Sqlstate, NativeError, MessageText, BufferLength, TextLength);
}


SQLRETURN SQL_API ODBCWrapper::SQLGetEnvAttr(SQLHENV EnvironmentHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER * StringLength)  {
	if (_fn_SQLGetEnvAttr==NULL) {
		cerr << "NULL function pointer for SQLGetEnvAttr" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLGetEnvAttr(EnvironmentHandle, Attribute, Value, BufferLength, StringLength);
}


SQLRETURN SQL_API ODBCWrapper::SQLGetInfo(SQLHDBC ConnectionHandle, SQLUSMALLINT InfoType, SQLPOINTER InfoValue, SQLSMALLINT BufferLength, SQLSMALLINT * StringLength)  {
	if (_fn_SQLGetInfo==NULL) {
		cerr << "NULL function pointer for SQLGetInfo" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLGetInfo(ConnectionHandle, InfoType, InfoValue, BufferLength, StringLength);
}


SQLRETURN SQL_API ODBCWrapper::SQLGetStmtAttr(SQLHSTMT StatementHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER * StringLength)  {
	if (_fn_SQLGetStmtAttr==NULL) {
		cerr << "NULL function pointer for SQLGetStmtAttr" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLGetStmtAttr(StatementHandle, Attribute, Value, BufferLength, StringLength);
}


SQLRETURN SQL_API ODBCWrapper::SQLGetStmtOption(SQLHSTMT StatementHandle, SQLUSMALLINT Option, SQLPOINTER Value)  {
	if (_fn_SQLGetStmtOption==NULL) {
		cerr << "NULL function pointer for SQLGetStmtOption" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLGetStmtOption(StatementHandle, Option, Value);
}


SQLRETURN SQL_API ODBCWrapper::SQLGetTypeInfo(SQLHSTMT StatementHandle, SQLSMALLINT DataType)  {
	if (_fn_SQLGetTypeInfo==NULL) {
		cerr << "NULL function pointer for SQLGetTypeInfo" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLGetTypeInfo(StatementHandle, DataType);
}


SQLRETURN SQL_API ODBCWrapper::SQLNumResultCols(SQLHSTMT StatementHandle, SQLSMALLINT * ColumnCount)  {
	if (_fn_SQLNumResultCols==NULL) {
		cerr << "NULL function pointer for SQLNumResultCols" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLNumResultCols(StatementHandle, ColumnCount);
}


SQLRETURN SQL_API ODBCWrapper::SQLParamData(SQLHSTMT StatementHandle, SQLPOINTER * Value)  {
	if (_fn_SQLParamData==NULL) {
		cerr << "NULL function pointer for SQLParamData" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLParamData(StatementHandle, Value);
}


SQLRETURN SQL_API ODBCWrapper::SQLPrepare(SQLHSTMT StatementHandle, SQLCHAR * StatementText, SQLINTEGER TextLength)  {
	if (_fn_SQLPrepare==NULL) {
		cerr << "NULL function pointer for SQLPrepare" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLPrepare(StatementHandle, StatementText, TextLength);
}


SQLRETURN SQL_API ODBCWrapper::SQLPutData(SQLHSTMT StatementHandle, SQLPOINTER Data, SQLLEN StrLen_or_Ind)  {
	if (_fn_SQLPutData==NULL) {
		cerr << "NULL function pointer for SQLPutData" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLPutData(StatementHandle, Data, StrLen_or_Ind);
}


SQLRETURN SQL_API ODBCWrapper::SQLRowCount(SQLHSTMT StatementHandle, SQLLEN * RowCount)  {
	if (_fn_SQLRowCount==NULL) {
		cerr << "NULL function pointer for SQLRowCount" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLRowCount(StatementHandle, RowCount);
}


SQLRETURN SQL_API ODBCWrapper::SQLSetConnectAttr(SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength)  {
	if (_fn_SQLSetConnectAttr==NULL) {
		cerr << "NULL function pointer for SQLSetConnectAttr" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLSetConnectAttr(ConnectionHandle, Attribute, Value, StringLength);
}


SQLRETURN SQL_API ODBCWrapper::SQLSetConnectOption(SQLHDBC ConnectionHandle, SQLUSMALLINT Option, SQLULEN Value)  {
	if (_fn_SQLSetConnectOption==NULL) {
		cerr << "NULL function pointer for SQLSetConnectOption" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLSetConnectOption(ConnectionHandle, Option, Value);
}


SQLRETURN SQL_API ODBCWrapper::SQLSetCursorName(SQLHSTMT StatementHandle, SQLCHAR * CursorName, SQLSMALLINT NameLength)  {
	if (_fn_SQLSetCursorName==NULL) {
		cerr << "NULL function pointer for SQLSetCursorName" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLSetCursorName(StatementHandle, CursorName, NameLength);
}


SQLRETURN SQL_API ODBCWrapper::SQLSetDescField(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, SQLPOINTER Value, SQLINTEGER BufferLength)  {
	if (_fn_SQLSetDescField==NULL) {
		cerr << "NULL function pointer for SQLSetDescField" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLSetDescField(DescriptorHandle, RecNumber, FieldIdentifier, Value, BufferLength);
}


SQLRETURN SQL_API ODBCWrapper::SQLSetDescRec(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, SQLSMALLINT Type, SQLSMALLINT SubType, SQLLEN Length, SQLSMALLINT Precision, SQLSMALLINT Scale, SQLPOINTER Data, SQLLEN * StringLength, SQLLEN * Indicator)  {
	if (_fn_SQLSetDescRec==NULL) {
		cerr << "NULL function pointer for SQLSetDescRec" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLSetDescRec(DescriptorHandle, RecNumber, Type, SubType, Length, Precision, Scale, Data, StringLength, Indicator);
}


SQLRETURN SQL_API ODBCWrapper::SQLSetEnvAttr(SQLHENV EnvironmentHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength)  {
	if (_fn_SQLSetEnvAttr==NULL) {
		cerr << "NULL function pointer for SQLSetEnvAttr" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLSetEnvAttr(EnvironmentHandle, Attribute, Value, StringLength);
}


SQLRETURN SQL_API ODBCWrapper::SQLSetStmtAttr(SQLHSTMT StatementHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength)  {
	if (_fn_SQLSetStmtAttr==NULL) {
		cerr << "NULL function pointer for SQLSetStmtAttr" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLSetStmtAttr(StatementHandle, Attribute, Value, StringLength);
}


SQLRETURN SQL_API ODBCWrapper::SQLSetStmtOption(SQLHSTMT StatementHandle, SQLUSMALLINT Option, SQLULEN Value)  {
	if (_fn_SQLSetStmtOption==NULL) {
		cerr << "NULL function pointer for SQLSetStmtOption" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLSetStmtOption(StatementHandle, Option, Value);
}


SQLRETURN SQL_API ODBCWrapper::SQLSpecialColumns(SQLHSTMT StatementHandle, SQLUSMALLINT IdentifierType, SQLCHAR * CatalogName, SQLSMALLINT NameLength1, SQLCHAR * SchemaName, SQLSMALLINT NameLength2, SQLCHAR * TableName, SQLSMALLINT NameLength3, SQLUSMALLINT Scope, SQLUSMALLINT Nullable)  {
	if (_fn_SQLSpecialColumns==NULL) {
		cerr << "NULL function pointer for SQLSpecialColumns" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLSpecialColumns(StatementHandle, IdentifierType, CatalogName, NameLength1, SchemaName, NameLength2, TableName, NameLength3, Scope, Nullable);
}


SQLRETURN SQL_API ODBCWrapper::SQLStatistics(SQLHSTMT StatementHandle, SQLCHAR * CatalogName, SQLSMALLINT NameLength1, SQLCHAR * SchemaName, SQLSMALLINT NameLength2, SQLCHAR * TableName, SQLSMALLINT NameLength3, SQLUSMALLINT Unique, SQLUSMALLINT Reserved)  {
	if (_fn_SQLStatistics==NULL) {
		cerr << "NULL function pointer for SQLStatistics" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLStatistics(StatementHandle, CatalogName, NameLength1, SchemaName, NameLength2, TableName, NameLength3, Unique, Reserved);
}


SQLRETURN SQL_API ODBCWrapper::SQLTables(SQLHSTMT StatementHandle, SQLCHAR * CatalogName, SQLSMALLINT NameLength1, SQLCHAR * SchemaName, SQLSMALLINT NameLength2, SQLCHAR * TableName, SQLSMALLINT NameLength3, SQLCHAR * TableType, SQLSMALLINT NameLength4)  {
	if (_fn_SQLTables==NULL) {
		cerr << "NULL function pointer for SQLTables" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLTables(StatementHandle, CatalogName, NameLength1, SchemaName, NameLength2, TableName, NameLength3, TableType, NameLength4);
}


SQLRETURN SQL_API ODBCWrapper::SQLTransact(SQLHENV EnvironmentHandle, SQLHDBC ConnectionHandle, SQLUSMALLINT CompletionType)  {
	if (_fn_SQLTransact==NULL) {
		cerr << "NULL function pointer for SQLTransact" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLTransact(EnvironmentHandle, ConnectionHandle, CompletionType);
}


SQLRETURN SQL_API ODBCWrapper::SQLSetParam(SQLHSTMT StatementHandle, SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType, SQLSMALLINT ParameterType, SQLULEN LengthPrecision, SQLSMALLINT ParameterScale, SQLPOINTER ParameterValue, SQLLEN * StrLen_or_Ind)  {
	if (_fn_SQLSetParam==NULL) {
		cerr << "NULL function pointer for SQLSetParam" << endl;
		return SQL_ERROR;
	}
	return _fn_SQLSetParam(StatementHandle, ParameterNumber, ValueType, ParameterType, LengthPrecision, ParameterScale, ParameterValue, StrLen_or_Ind);
}

